/*
    This file is part of cpp-ethereum.

    cpp-ethereum is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    cpp-ethereum is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with cpp-ethereum.  If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Worker.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/

// Modified by Evgeniy Sukhomlinov 2018

#pragma once

#include <string>
#include <thread>
#include <atomic>
#include <cassert>
#include "Guards.h"

namespace XDag
{
    enum class WorkerState
    {
        Starting,
        Started,
        Stopping,
        Stopped,
        Killing
    };

    class Worker
    {
    public:
        Worker(std::string const& name) : _name(name) {}

        Worker(Worker const&) = delete;
        Worker& operator=(Worker const&) = delete;

        virtual ~Worker();

        /// Starts worker thread; causes startedWorking() to be called.
        void StartWorking();

        /// Stop worker thread; causes call to stopWorking().
        void StopWorking();

        bool ShouldStop() const { return _state != WorkerState::Started; }

    private:
        virtual void WorkLoop() = 0;

        std::string _name;

        mutable Mutex _workLock;						///< Lock for the network existance.
        std::unique_ptr<std::thread> _workerThread;		///< The worker thread.
        std::atomic<WorkerState> _state = { WorkerState::Starting };
    };
}
